// package com.zzht.patrol.bp.calculate.utils;
//
// import com.zzht.bp.common.util.GeomMathUtil;
// import com.zzht.bp.common.util.ListUtils;
// import com.zzht.bp.computing.util.NumberUtil;
// import com.zzht.bp.trace.model.Position;
// import com.zzht.patrol.bp.calculate.model.task.PatrolTaskLine;
// import com.zzht.patrol.bp.calculate.model.task.PatrolTaskSubLine;
// import com.zzht.patrol.database.geometry.Path;
// import com.zzht.patrol.database.geometry.Point;
// import com.zzht.patrol.database.geometry.Polyline;
// import lombok.extern.log4j.Log4j2;
//
// import java.math.BigDecimal;
// import java.util.ArrayList;
// import java.util.HashMap;
// import java.util.List;
//
// /**
//  * @author xiongweitao
//  * @version V1.0 Created on 2021/6/11
//  * @title LineUtil
//  * @Description:
//  */
// @Log4j2
// public class LineUtil {
//     /**
//      * 最长插值距离，如果超过这个距离，将不再插值
//      */
//     private static final int MAX_TRACE_INTERPOLATION_LEN = 2000;
//
//     /**
//      * 管线的切割
//      *
//      * @return
//      */
//
//     public static List<PatrolTaskSubLine> interpolationTaskLine(PatrolTaskLine patrolTaskLine) {
//         return interpolationTaskLine(patrolTaskLine.getGeom().getPaths(), patrolTaskLine.getLineLen(), patrolTaskLine.getLineId(), patrolTaskLine.getBuffer(), patrolTaskLine.getTaskId());
//     }
//
//     public static List<PatrolTaskSubLine> interpolationTaskLine(List<Path> pathList, double lineLength, long lineId, int buffer, Long taskId) {
//         long index = 0;
//         List<PatrolTaskSubLine> taskLineList = new ArrayList<>(16);
//         int size = pathList.size();
//         double tmpLengthSum = 0;
//         for (int i = 0; i < size; i++) {
//             Path path = pathList.get(i);
//             if (null == path || ListUtils.isEmpty(path.getPointArray())) {
//                 continue;
//             }
//             double pathLen;
//             if (i == (size - 1)) {
//                 //如果线段已经是最后一段，则最后一段的长度保证总长度一致
//                 pathLen = NumberUtil.sub(lineLength, tmpLengthSum);
//                 if (pathLen < 0.001) {
//                     pathLen = getPathLength(path);
//                 }
//             } else {
//                 pathLen = getPathLength(path);
//                 tmpLengthSum = NumberUtil.add(tmpLengthSum, pathLen);
//             }
//             List<PatrolTaskSubLine> tmpTaskLineList = interpolationTaskLine(path.getPointArray(), pathLen, lineId, buffer, index, taskId);
//             if (!ListUtils.isEmpty(tmpTaskLineList)) {
//                 taskLineList.addAll(tmpTaskLineList);
//                 index = taskLineList.size();
//             }
//         }
//
//         if (ListUtils.isEmpty(taskLineList)) {
//             return taskLineList;
//         }
//         return taskLineList;
//     }
//
//
//     /**
//      * 切割计划任务线
//      *
//      * @param pathPointList 待切割的计划任务线
//      * @param lineLength    线的总长度
//      * @param lineId        线编号
//      * @param buffer        切割半径，缓冲半径
//      * @return List<PatrolTaskSubLine>
//      */
//     private static List<PatrolTaskSubLine> interpolationTaskLine(List<Point> pathPointList, double lineLength, long lineId, int buffer, long startIndex, Long taskId) {
//         List<PatrolTaskSubLine> taskLineList = new ArrayList<>(16);
//         if (ListUtils.isEmpty(pathPointList)) {
//             return taskLineList;
//         }
//
//         double tmpLengthSum = 0;
//         Point lastPnt = null;
//         for (int i = 0, size = pathPointList.size(); i < size - 1; i++) {
//             Point sPnt = pathPointList.get(i);
//             if (null == lastPnt) {
//                 lastPnt = sPnt;
//             }
//
//             Point ePnt = pathPointList.get(i + 1);
//             if (isEqual(lastPnt, ePnt)) {
// //                if (lineLength > 0.001 && startIndex > 0 && i == size - 2) {
// //                    // 关键线绘制双击完成，线段最后一段为同一点位，不需存储
// //                    continue;
// //                }
// //                //处理特别短的管线
// //                PatrolTaskSubLine taskLine = buildTaskLine(lastPnt, ePnt, lineLength, lineId, startIndex, taskId);
// //                taskLineList.add(taskLine);
//                 continue;
//             }
//             double subLineLength;
//             if (i == (size - 2)) {
//                 //如果线段已经是最后一段，则最后一段的长度保证总长度一致
//                 subLineLength = NumberUtil.sub(lineLength, tmpLengthSum);
//             } else {
//                 subLineLength = distance(lastPnt, ePnt);
//                 tmpLengthSum = NumberUtil.add(tmpLengthSum, subLineLength);
//             }
//
//             if (subLineLength > buffer) {
//                 List<PatrolTaskSubLine> lineList = interpolationTaskLine(lastPnt, ePnt, subLineLength, lineId, buffer, startIndex, taskId);
//                 if (!ListUtils.isEmpty(lineList)) {
//                     taskLineList.addAll(lineList);
//                     startIndex += lineList.size();
//                 }
//             } else {
//                 PatrolTaskSubLine taskLine = buildTaskLine(lastPnt, ePnt, subLineLength, lineId, startIndex, taskId);
//                 taskLineList.add(taskLine);
//                 startIndex++;
//             }
//             lastPnt = ePnt;
//         }
//
//         return taskLineList;
//     }
//
//
//     private static List<PatrolTaskSubLine> interpolationTaskLine(Point startPoint, Point endPoint, double linelen, long lineId, int buffer, long index, Long taskId) {
//         List<Point> interpolationPointList = interpolationLine(startPoint, endPoint, buffer);
//         double tmpSubLengthSum = 0;
//         List<PatrolTaskSubLine> taskLineList = new ArrayList<>(16);
//         Point lastSubPnt = null;
//         for (int k = 0, subSize = interpolationPointList.size(); k < subSize - 1; k++) {
//             Point stPoint = interpolationPointList.get(k);
//             if (0 == k) {
//                 lastSubPnt = stPoint;
//             }
//
//             Point edPoint = interpolationPointList.get(k + 1);
//             if (isEqual(lastSubPnt, edPoint)) {
// //                if (linelen > 0.001 && index > 0 && k == subSize - 2) {
// //                    // 关键线绘制双击完成，线段最后一段为同一点位，不需存储
// //                    continue;
// //                }
// //                //处理特别短的管线
// //                PatrolTaskSubLine taskLine = buildTaskLine(lastSubPnt, edPoint, linelen, lineId, index, taskId);
// //                taskLineList.add(taskLine);
//                 continue;
//             }
//
//             double distance;
//             if (k == (subSize - 2)) {
//                 distance = NumberUtil.sub(linelen, tmpSubLengthSum);
//             } else {
//                 distance = buffer;
//                 tmpSubLengthSum = NumberUtil.add(tmpSubLengthSum, distance);
//             }
//
//             PatrolTaskSubLine taskLine = buildTaskLine(lastSubPnt, edPoint, distance, lineId, index, taskId);
//             taskLineList.add(taskLine);
//             lastSubPnt = edPoint;
//             index++;
//         }
//         return taskLineList;
//     }
//
//     /***
//      * 构建计划任务线
//      * @param stPoint 起始点
//      * @param edPoint 结束点
//      * @param lineLength 线长度
//      * @param lineId 线编号
//      * @param index 线上索引号
//      * @return PatrolTaskLine
//      */
//     private static PatrolTaskSubLine buildTaskLine(Point stPoint, Point edPoint, double lineLength, long lineId, long index, Long taskId) {
//         if (null == stPoint || null == edPoint) {
//             return null;
//         }
//         PatrolTaskSubLine taskLine = new PatrolTaskSubLine();
//         taskLine.setLineId(lineId);
//         taskLine.setTaskId(taskId);
//         taskLine.setSubIndex(index);
//         taskLine.setStartX(stPoint.getX());
//         taskLine.setStartY(stPoint.getY());
//         taskLine.setEndX(edPoint.getX());
//         taskLine.setEndY(edPoint.getY());
//         taskLine.setLength(lineLength);
//         taskLine.setCover((byte) 0);
//
//         List<Path> pathList = new ArrayList<>(16);
//         Path path = LineUtil.taskLineToGeoPath(taskLine);
//         pathList.add(path);
//         Polyline polyline = new Polyline();
//         polyline.setPaths(pathList);
//         taskLine.setGeom(polyline);
//         return taskLine;
//     }
//
//     /**
//      * 将任务线段转成几何
//      *
//      * @param taskLine 任务线段
//      * @return Path
//      */
//     public static Path taskLineToGeoPath(PatrolTaskSubLine taskLine) {
//         if (null == taskLine) {
//             return null;
//         }
//         Path path = new Path();
//         List<Point> pointList = new ArrayList<>(3);
//         pointList.add(new Point(taskLine.getStartX(), taskLine.getStartY()));
//         pointList.add(new Point(taskLine.getEndX(), taskLine.getEndY()));
//         path.setPointArray(pointList);
//         return path;
//     }
//
//     /**
//      * 将两个点之间按照指定的距离插值
//      *
//      * @param stPoint 开始点
//      * @param edPoint 结束点
//      * @param buffer  插值长度
//      * @return List<Point>
//      */
//     private static List<Point> interpolationLine(Point stPoint, Point edPoint, int buffer) {
//         //如果当前的管段的长度大于设置的最大长度，则线上插值
//         List<Point> points = new ArrayList<>();
//         if (null == stPoint || null == edPoint) {
//             return points;
//         }
//         double dis = distance(stPoint, edPoint);
//         if (dis <= buffer) {
//             points.add(stPoint);
//             points.add(edPoint);
//             return points;
//         }
//
//         int index = 1;
//         double stepX = (edPoint.getX() - stPoint.getX()) * buffer / dis;
//         double stepY = (edPoint.getY() - stPoint.getY()) * buffer / dis;
//         points.add(stPoint);
//         Point lastPnt = stPoint;
//         while (dis > buffer) {
//             double x = BigDecimal.valueOf(stPoint.getX() + stepX * index).setScale(5, BigDecimal.ROUND_HALF_UP)
//                     .doubleValue();
//             double y = BigDecimal.valueOf(stPoint.getY() + stepY * index).setScale(5, BigDecimal.ROUND_HALF_UP)
//                     .doubleValue();
//             Point curPt = new Point(x, y);
//             if (isEqual(lastPnt, curPt)) {
//                 break;
//             }
//             dis -= distance(lastPnt, curPt);
//             points.add(curPt);
//             lastPnt = curPt;
//             index++;
//         }
//
//         if (dis > 0) {
//             points.add(edPoint);
//         }
//
//         return points;
//     }
//
//
//     private static double getPathLength(Path path) {
//         List<Point> pointList = path.getPointArray();
//         if (ListUtils.isEmpty(pointList)) {
//             return 0;
//         }
//         double subLineLength = 0;
//         Point lastPnt = null;
//         for (int i = 0, size = pointList.size(); i < size - 1; i++) {
//             Point sPnt = pointList.get(i);
//             if (i == 0) {
//                 lastPnt = sPnt;
//             }
//             Point ePnt = pointList.get(i + 1);
//             if (isEqual(lastPnt, ePnt)) {
//                 continue;
//             }
//             subLineLength += distance(lastPnt, ePnt);
//             lastPnt = ePnt;
//         }
//
//         return subLineLength;
//     }
//
//     private static boolean isEqual(Point a, Point b) {
//         if (a == null && b == null) {
//             return true;
//         }
//
//         if (a == null) {
//             return false;
//         }
//
//         if (b == null) {
//             return false;
//         }
//
//         return isEqual(a.getX(), b.getX()) && isEqual(a.getY(), b.getY());
//     }
//
//     private static boolean isEqual(double a, double b) {
//         return Math.abs(a - b) < 0.0000001;
//     }
//
//     /**
//      * @param stPoint start point
//      * @param edPoint end point
//      * @return 高斯平面距离
//      */
//     private static double distance(Point stPoint, Point edPoint) {
//         if (null == stPoint || null == edPoint) {
//             return 0;
//         }
//
//         return distance(stPoint.getX(), stPoint.getY(), edPoint.getX(), edPoint.getY());
//     }
//
//     private static double distance(double x0, double y0, double x1, double y1) {
//         double distance = GeomMathUtil.calculatePlaneDistance(x0, y0, x1, y1);
//         distance = GeomMathUtil.formatDouble(distance);
//         return distance;
//     }
//
//     /**
//      * 将两个点之间按照指定的距离插值, 两点变一组点.
//      *
//      * @param stPoint 开始点
//      * @param edPoint 结束点
//      * @param buffer  插值长度
//      * @return List<Position>
//      */
//     public static List<Position> interpolationPosition(Position stPoint, Position edPoint, double buffer) {
//         List<Position> points = new ArrayList<>();
//         //如果当前的管段的长度大于设置的最大长度，则线上插值(这句注释貌似和代码毫无关系)
//         if (null == stPoint && null == edPoint) {
//             return points;
//         }
//
//         if (null == stPoint) {
//             points.add(edPoint);
//             return points;
//         }
//
//         if (null == edPoint) {
//             points.add(stPoint);
//             return points;
//         }
//
//         // 计算出两点在二维平面坐标系上的距离(不考虑z轴)
//         double distance = GeomMathUtil.calculatePlaneDistance(stPoint.getX(), stPoint.getY(), edPoint.getX(), edPoint.getY());
//         // 保留2位小数
//         distance = GeomMathUtil.formatDouble(distance);
//
//         if (cn.hutool.core.util.NumberUtil.equals(distance, 0)) {
//             points.add(stPoint);
//             return points;
//         }
//
//         // 如果间隔太大,不进行插值,防止大量损耗CPU资源
//         if (distance > MAX_TRACE_INTERPOLATION_LEN) {
//             points.add(stPoint);
//             points.add(edPoint);
//             return points;
//         }
//
//         // 两点距离小于步长,不进行插值.
//         if (distance <= buffer) {
//             points.add(stPoint);
//             points.add(edPoint);
//             return points;
//         }
//
//         int stepNum = (int) Math.ceil(distance / buffer);
//         double stepX = (edPoint.getX() - stPoint.getX()) / stepNum;
//         double stepY = (edPoint.getY() - stPoint.getY()) / stepNum;
//         double stepLon = (edPoint.getLon() - stPoint.getLon()) / stepNum;
//         double stepLat = (edPoint.getLat() - stPoint.getLat()) / stepNum;
//
//         points.add(stPoint);
//         for (int i = 1; i < stepNum - 1; i++) {
//             distance -= buffer;
//             Position curPt = new Position();
//             curPt.setX(stPoint.getX() + stepX * i);
//             curPt.setY(stPoint.getY() + stepY * i);
//             curPt.setLon(stPoint.getLon() + stepLon * i);
//             curPt.setLat(stPoint.getLat() + stepLat * i);
//             curPt.setAccuracy(stPoint.getAccuracy());
//             curPt.setUserId(stPoint.getUserId());
//             curPt.setGpsTime(stPoint.getGpsTime());
//             curPt.setDeviceId(stPoint.getDeviceId());
//             curPt.setAltitude(stPoint.getAltitude());
//             curPt.setCourse(stPoint.getCourse());
//             curPt.setBattery(stPoint.getBattery());
//             curPt.setSpeed(stPoint.getSpeed());
//             curPt.setMock(1);
//             curPt.setUserName(stPoint.getUserName());
//             curPt.setTrueName(stPoint.getTrueName());
//             curPt.setTenantId(stPoint.getTenantId());
//             points.add(curPt);
//         }
//         points.add(edPoint);
//         return points;
//     }
//
//     public static List<HashMap<String, Object>> mergePipeLine(List<PatrolTaskSubLine> subLines) {
//         com.zzht.patrol.bp.calculate.utils.Line2Pipe pipe = new com.zzht.patrol.bp.calculate.utils.Line2Pipe();
//         pipe.getList().clear();
//         List<com.zzht.patrol.bp.calculate.utils.LIN_DATA> linData = pipe.cacheLinData(subLines);
//         List<List<com.zzht.patrol.bp.calculate.utils.LIN_DATA>> pipeByLine = pipe.createPipeByLine(linData);
//         pipe.pipes2polyline(pipeByLine);
//         return pipe.getList();
//     }
//
//
// }
